from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from mall import settings
from django.utils.deconstruct import deconstructible
import os


# 自定义文件系统必须继承django自带的文件系统
# 需要为存储类添加django.utils.deconstruct.deconstructible装饰器
@deconstructible
class MyStorage(Storage):
    def __init__(self, conf_path=None, ip=None):
        if conf_path is None:
            conf_path = settings.FDFS_CLIENT_CONF
        self.conf_path = conf_path

        if ip is None:
            ip = settings.FDFS_URL
        self.ip = ip

    def _open(self, name, mode='rb'):
        pass

    def _save(self, name, content):
        """
        name是传入的文件名，content是Django接收到的文件内容，该方法需要将content文件内容保存。
        """
        # 创建上传文件的客户端
        client = Fdfs_client(self.conf_path)
        # 获取文件二进制内容
        file_data = content.read()
        # 上传二进制文件, 直接上传文件用 upload_by_filename
        result = client.upload_appender_by_buffer(file_data)
        # result 是一个上传结果的字典
        if result['Status'] == 'Upload successed.':
            # Remote file_id 是返回的url 端口后面的部分
            return result['Remote file_id']
        else:
            raise Exception('上传失败')

    # 检查要上传的文件名是否在文件系统中已存在
    def exists(self, name):
        """
        因为 fastdfs 文件系统会自定义文件名， 确保文件名不冲突， 所以直接返回false
        """
        return False

    # 返回文件的完整访问URL
    def url(self, name):
        return self.ip + name
        # return os.path.join(settings.FDFS_URL, name)
